/*
 * Copyright (c) 2024 Shenzhen Kaihong Digital Industry Development Co., Ltd.
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 * http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */

#ifndef KH_SLE_CONNECT_H
#define KH_SLE_CONNECT_H

#ifdef __cplusplus
extern "C" {
#endif

#include <stdint.h>
#include <stdlib.h>
#include "sle_error_code.h"
#include "sle_device_config.h"
#include "sle_connect_config.h"

/**
 * @brief   Callback invoked when the SLE connect state changed.
 *
 * @param   [in] connectId                 - Indicates the ID of the SLE connect.
 * @param   [in] addr                   - Indicates the remote device's address.
 * @param   [in] connState              - Indicate the connect state {@link SleConnectState}.
 * @param   [in] discReason             - Indicate the disconnect reason {@link SleDisconnectReason}.
 * @return  None
 */
typedef void (*SleConnectStateChange)(uint16_t connectId, const SleDeviceAddress *addr
        , SleConnectState connState, SlePairState pairState, SleDisConnectReason discReason);

/**
 * @brief   Callback invoked when the SLE connect parameter changed.
 *
 * @param   [in] connectId                 - Indicates the ID of the SLE connection.
 * @param   [in] errCode                - Indicate the operation result status @link SleErrorCode
 * @param   [in] connParam              - Indicate the connect parameter {@link SleConnectionParamUpdateEvt}.
 * @return  None
 */
typedef void (*SleConnParamUpdated)(uint16_t connectId, SleErrorCode errCode, const SleConnectionParamUpdateEvt *connParam);

typedef struct {
    SleConnectStateChange OnSleConnStateChangeCb;
    SleConnParamUpdated OnSleConnParamUpdatedCb;
} SleConnectCallbacks;

/**
 * @brief   Initialize the SLE connection module.
 *
 * @param   None
 * @return  Returns the operation result status @link SleErrorCode
 */
SleErrorCode InitSleConnectService(void);

/**
 * @brief   Deinitialize the SLE connection module.
 *
 * @param   None
 * @return  Returns the operation result status @link SleErrorCode
 */
SleErrorCode DeinitSleConnectService(void);

/**
 * @brief   Create a SLE connection to a remote device [Async: result return in @link OnSleConnStateChangeCb]
 *
 * @param   [in] remoteAddr Indicates the remote device's address.
 * @return  Returns the operation result status @link SleErrorCode
 *
 * @note    Result will return in @link SleConnectStateChange
 */
SleErrorCode SleConnect(const SleDeviceAddress *remoteAddr);

/**
 * @brief   Disconnect a SLE connection to a remote device [Async: result return in @link OnSleConnStateChangeCb]
 *
 * @param   [in] remoteAddr Indicates the remote device's address.
 * @return  Returns the operation result status @link SleErrorCode
 *
 * @note    Result will return in @link SleConnectStateChange
 */
SleErrorCode SleDisconnect(const SleDeviceAddress *remoteAddr);

/**
 * @brief   Update the parameters of the SLE connection. [Async: result return in @link OnSleConnParamUpdatedCb]
 *
 * @param   [in] connectId Indicates the ID of the SLE connection.
 * @param   [in] connParam Indicate the connect parameter {@link SleConnectParam}.
 * @return  Returns the operation result status @link SleErrorCode
 *
 * @note    Result will return in @link SleConnParamUpdated
 */
SleErrorCode SleUpdateConnParam(const SleConnectionParamUpdate *param);

/**
 * @brief   Update the parameters of the ALL SLE connection. [Async: result return in @link OnSleConnParamUpdatedCb]
 *
 * @param   [out] connectDevList Indicates the ID list of the connected devices.
 * @param   [out] success update dev num.
 * @return  Returns the operation result status @link SleErrorCode
 *
 * @note    Result will return in @link SleConnParamUpdated
 */
SleErrorCode SleUpdateAllConnParam(SleConnectDev *successUpdateDevList, uint16_t *successUpdateNum);

/**
 * @brief   Get recommend send data size by connect id
 *
 * @param   [in] connect Id.
 * @param   [out] recommend send data size.
 * @return  Returns the operation result status @link SleErrorCode
 *
 */
SleErrorCode SleGetRecomSendDataSize(uint16_t connectId, uint32_t *recomSendDataSize);

/**
 * @brief   Send pair request. [Async: result return in @link OnSleConnStateChangeCb]
 *
 * @param   [in] remoteAddr Indicates the remote device's address.
 * @return  Returns the operation result status @link SleErrorCode
 */
SleErrorCode SendPairReq(const SleDeviceAddress *remoteAddr);

/**
 * @brief Remove a pair device.
 *
 * @param   [in] remoteAddr Indicates the remote device's address.
 * @return  Returns the operation result status @link SleErrorCode
 */
SleErrorCode RemovePair(const SleDeviceAddress *remoteAddr);

/**
 * @brief Remove all pair devices.
 *
 * @param   None
 * @return  Returns the operation result status @link SleErrorCode
 */
SleErrorCode RemoveAllPairs(void);

/**
 * @brief Gets paired devices.
 *
 * @param   [in] addr Indicates the remote device's address.
 * @param   [out] pairState is the pair state of the remote device.
 * @return  SleErrorCode - operation result
 */
SleErrorCode GetDevicePairState(const SleDeviceAddress *addr, SlePairState *pairState);

/**
 * @brief   Read rssi value of the remote device sync.
 *
 * @param   [in] connectId Indicates the ID of the SLE connection.
 * @param   [out] rssi  Indicates the remote device's rssi value.
 * @return  Returns the operation result status @link SleErrorCode
 */
SleErrorCode ReadRemoteRssi(uint16_t connectId, int8_t *rssi);

/**
 * @brief   Gets the ID list of the connected devices.
 *
 * @param   [out] connectDevList Indicates the ID list of the connected devices.
 * @param   [inout] connectNum Input the size of the list and indicates the number of the current connected devices.
 * @return  Returns the operation result status @link SleErrorCode
 *
 * @note    len of connectDevList should be connectDevList[SLE_MAX_CONNECT_ID_NUM] as input, connectNum should less then SLE_MAX_CONNECT_ID_NUM as input.
 */
SleErrorCode GetConnectDevList(SleConnectDev *connectDevList, uint16_t *connectNum);

/**
 * @brief   Gets the ID of the connected device.
 *
 * @param   [in] remoteDeviceAddr Indicates the remote device's address.
 * @param   [out] connectId Indicates the ID of the connected device.
 * @return  Returns the ID of the connected device.
 */
SleErrorCode GetConnectDeviceId(const SleDeviceAddress *remoteDeviceAddr, uint16_t *connectId);

/**
 * @brief   Check whether the SLE connection is connected.
 *
 * @param   [in] connectId Indicates the ID of the SLE connection.
 * @return  Returns the operation result status @link SleErrorCode
 */
SleErrorCode CheckIsConnected(uint16_t connectId);

/**
 * @brief   Registers SLE connection callbacks.
 *
 * @param   [in] func Indicates the pointer to the callbacks to register, as enumerated in {@link SleConnectCallbacks}.
 * @return  Returns {@link OHOS_SLE_STATUS_SUCCESS} if the callbacks are registered;
 */
SleErrorCode RegisterConnectCallbacks(SleConnectCallbacks *func);

/**
 * @brief   Deregisters SLE connection callbacks.
 *
 * @param   [in] func Indicates the pointer to the callbacks to register, as enumerated in {@link SleConnectCallbacks}.
 * @return  Returns {@link OHOS_SLE_STATUS_SUCCESS} if the callbacks are registered;
 */
SleErrorCode UnregisterConnectCallbacks(SleConnectCallbacks *func);

#ifdef __cplusplus
}
#endif
#endif